﻿using CoachingOrganizer.ClientInfrastructure.ServicesEntities.LocalStorage.Tools.MoodLevel;
using CoachingOrganizer.Logic.Common;
using CoachingOrganizer.Logic.Logic.Common;
using CoachingOrganizer.Logic.Models.Tools.MoodLevel;
using CoachingOrganizer.Toolkit.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoachingOrganizer.Logic.Logic.Tools.MoodLevel
{
    internal class MoodLevelLogic : ToolLogicBase
    {
        private readonly MoodLevelModel _model;
        private readonly IMoodLevelInfo _localData;
        private readonly List<MoodValueLogic> _moodValues = new List<MoodValueLogic>();
        private MoodDayCacheLogic[] _days;

        public MoodLevelModel Model
        {
            get { return _model; }
        }

        public IMoodLevelInfo LocalData
        {
            get { return _localData; }
        }

        public MoodLevelLogic(MoodLevelModel model, LogicExtender logicExtender, GoalLogic upperLogic, IMoodLevelInfo localData)
            : base(model, logicExtender, upperLogic, localData)
        {
            _model = model;
            _localData = localData;
            model.EnumerateDayValuesDelegate = EnumerateDayValues;
            model.EnumerateMoodValuesDelegate = EnumerateMoodValues;
            model.UpdateDaysDelegate = UpdateDays;
            model.RemoveDelegate = Remove;
            model.SaveDelegate = Save;
        }

        public IEnumerable<MoodValueModel> EnumerateDayValues(DateTime day)
        {
            return _model.Values.Where(v => v.Time.Date == day);
        }

        public ActionResult<IMoodValueInfo> AddValue(DateTime time, double value)
        {
            ActionResult<IMoodValueInfo> addResult = _localData.AddNewMoodValue(i =>
            {
                i.Time = time;
                i.Value = value;
            });
            if (addResult.IsValid)
            {
                MoodValueLogic mooValueLogic = CreateMoodValueLogic(addResult.Result);
                _model.AddValue(mooValueLogic.Model);
            }
            return addResult;
        }

        private ActionResult Remove()
        {
            return _upperLogic.RemoveTool(this);
        }

        private ActionResult Save()
        {
            _localData.Start = _model.StartDate;
            _localData.Finish = _model.FinishDate;
            _localData.Period = _model.Period;
            return _localData.Save();
        }

        private void UpdateDays()
        {
            int daysCount = (int)Math.Max((_model.FinishDate - _model.StartDate).TotalDays, 0.0);
            _days = new MoodDayCacheLogic[daysCount];
            for (int i = 0; i < daysCount; i++)
                _days[i] = new MoodDayCacheLogic(_logicExtender, this, _model.StartDate.AddDays(i));
            _model.Days = _days.Select(l => l.Model).ToArray();
        }

        private ActionResult<IEnumerable<MoodValueLogic>> EnumerateMoodValues()
        {
            //ActionResult loadResult = _localData.LoadValues();
            IEnumerable<IMoodValueInfo> toolsInfo = _localData.MoodValuesInfo;
            return /*loadResult.IsValid ? */ActionResult<IEnumerable<MoodValueLogic>>.GetValidResult(toolsInfo.Select(i => CreateMoodValueLogic(i)));//: ActionResult<IEnumerable<MoodValueLogic>>.GetErrorResult(loadResult);
        }

        private MoodValueLogic CreateMoodValueLogic(IMoodValueInfo info)
        {
            MoodValueLogic outResult = new MoodValueLogic(new MoodValueModel
            {
                Time = info.Time,
                Value = info.Value
            }, _logicExtender, this, info);
            _moodValues.Add(outResult);
            return outResult;
        }
    }
}
